package com.ruoyi.erecord.employee.service.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.api.dto.employee.EmployeeImageDto;
import com.ruoyi.api.dto.employee.EmployeeMapDetailDto;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.tools.constant.ERecordConstant;
import com.ruoyi.common.tools.enums.DeviceTypeEnum;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.erecord.device.service.IDeviceService;
import com.ruoyi.erecord.employee.domain.Employee;
import com.ruoyi.erecord.employee.domain.bo.EmployeeBo;
import com.ruoyi.erecord.employee.domain.bo.EmployeeImportDetailBo;
import com.ruoyi.erecord.employee.domain.vo.EmployeeImportDetailVo;
import com.ruoyi.erecord.employee.domain.vo.EmployeeUserVo;
import com.ruoyi.erecord.employee.domain.vo.EmployeeVo;
import com.ruoyi.erecord.employee.mapper.EmployeeMapper;
import com.ruoyi.erecord.employee.service.IEmployeeImportDetailService;
import com.ruoyi.erecord.employee.service.IEmployeeService;
import com.ruoyi.erecord.samplebox.service.ISampleboxService;
import com.ruoyi.erecord.vehicles.service.IVehiclesService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;

/**
 * 人员Service业务层处理
 *
 * @author cc
 * @date 2023-04-13
 */
@RequiredArgsConstructor
@Service
public class EmployeeServiceImpl implements IEmployeeService {

	private final EmployeeMapper baseMapper;

	private final IEmployeeImportDetailService employeeImportDetailService;
	private final IVehiclesService vehiclesService;
	private final ISampleboxService sampleboxService;

	/**
	 * 查询人员
	 */
	@Override
	public EmployeeVo queryById(Long id) {
		return baseMapper.selectVoById(id);
	}

	/**
	 * 查询人员列表
	 */
	@Override
	public TableDataInfo<EmployeeVo> queryPageList(EmployeeBo bo, PageQuery pageQuery) {
		LambdaQueryWrapper<Employee> lqw = buildQueryWrapper(bo);
		Page<EmployeeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
		return TableDataInfo.build(result);
	}

	/**
	 * 查询人员列表
	 */
	@Override
	public List<EmployeeVo> queryList(EmployeeBo bo) {
		LambdaQueryWrapper<Employee> lqw = buildQueryWrapper(bo);
		return baseMapper.selectVoList(lqw);
	}

	private LambdaQueryWrapper<Employee> buildQueryWrapper(EmployeeBo bo) {
		Map<String, Object> params = bo.getParams();
		LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery();
		lqw.eq(StringUtils.isNotBlank(bo.getEmployeeCode()), Employee::getEmployeeCode, bo.getEmployeeCode());
		lqw.like(StringUtils.isNotBlank(bo.getEmployeeName()), Employee::getEmployeeName, bo.getEmployeeName());
		lqw.eq(bo.getSex() != null, Employee::getSex, bo.getSex());
		lqw.eq(StringUtils.isNotBlank(bo.getIdentityId()), Employee::getIdentityId, bo.getIdentityId());
		lqw.eq(bo.getDeptId() != null, Employee::getDeptId, bo.getDeptId());
		lqw.eq(bo.getEducation() != null, Employee::getEducation, bo.getEducation());
		return lqw;
	}

	/**
	 * 新增人员
	 */
	@Override
	public Boolean insertByBo(EmployeeBo bo) {
		Employee add = BeanUtil.toBean(bo, Employee.class);
		validEntityBeforeSave(add);
		boolean flag = baseMapper.insert(add) > 0;
		if (flag) {
			bo.setEmployeeCode(add.getEmployeeCode());
		}
		return flag;
	}

	/**
	 * 修改人员
	 */
	@Override
	public Boolean updateByBo(EmployeeBo bo) {
		Employee update = BeanUtil.toBean(bo, Employee.class);
		validEntityBeforeSave(update);
		return baseMapper.updateById(update) > 0;
	}

	/**
	 * 保存前的数据校验
	 */
	private void validEntityBeforeSave(Employee entity) {
		// TODO 做一些数据校验,如唯一约束
		if (entity.getId() == null) {
			Long o = this.getEmployeeIdByCode(entity.getEmployeeCode());
			if (null != o) {
				throw new ServiceException("人员编码 已经存在了！");
			}
		}
	}

	/**
	 * 批量删除人员
	 */
	@Override
	public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
		if (isValid) {
			// TODO 做一些业务上的校验,判断是否需要校验
			for (Long id : ids) {
				if (this.vehiclesService.isUseEmployeeId(id)) {
					throw new ServiceException(StrUtil.format("人员编码[ {} ] 被其他模块使用，不能删除！", this.getEmpCodeById(id)));
				}
				if (this.sampleboxService.isUseEmployeeId(id)) {
					throw new ServiceException(StrUtil.format("人员编码[ {} ] 被其他模块使用，不能删除！", this.getEmpCodeById(id)));
				}
				if (((IDeviceService) SpringUtils.getBean(IDeviceService.class)).isUseById(DeviceTypeEnum.USER,
						id)) {
					throw new ServiceException(StrUtil.format("人员编码[ {} ] 被其他模块使用，不能删除！", this.getEmpCodeById(id)));
				}
			}
		}
		return baseMapper.deleteBatchIds(ids) > 0;
	}

	@Override
	public Boolean batchInsertOrUpdate(String batchNo) {
		EmployeeImportDetailBo queryBo = new EmployeeImportDetailBo();
		queryBo.setBatchNo(batchNo);
		List<EmployeeImportDetailVo> detailList = this.employeeImportDetailService.queryList(queryBo);
		List<Employee> list = BeanCopyUtils.copyList(detailList, Employee.class);
		list.forEach(e -> {
			e.setId(this.getEmployeeIdByCode(e.getEmployeeCode()));
			e.restBase();
		});
		return this.baseMapper.insertOrUpdateBatch(list);
	}

	@Override
	public List<EmployeeUserVo> getEmployeeUserVoList(String name) {
		EmployeeBo bo = new EmployeeBo();
		bo.setEmployeeName(name);
		LambdaQueryWrapper<Employee> lqw = buildQueryWrapper(bo);
		lqw.last("limit 10");
		List<Employee> eList = baseMapper.selectList(lqw);
		List<EmployeeUserVo> list = BeanCopyUtils.copyList(eList, EmployeeUserVo.class);
		return list;
	}

	@Override
	public String getEmployeeNameById(Long id) {
		if (null == id)
			return null;
		Employee o = this.baseMapper.selectById(id);
		if (null != o) {
			return o.getEmployeeName();
		}
		return null;
	}

	@Override
	public Long getEmployeeIdByName(String name) {
		LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery();
		lqw.eq(Employee::getEmployeeName, name);
		lqw.last("limit 1");
		Employee o = this.baseMapper.selectOne(lqw);
		if (null != o) {
			return o.getId();
		}
		return null;
	}

	@Override
	public Boolean batchUpdate(List<EmployeeImportDetailVo> voList) {
		List<Employee> list = BeanCopyUtils.copyList(voList, Employee.class);
		list.forEach(e -> {
			e.setId(this.getEmployeeIdByCode(e.getEmployeeCode()));
			e.restBase();
		});
		return this.baseMapper.updateBatchById(list);
	}

	@Override
	public EmployeeUserVo getEmployeeUserVoByName(String name) {
		LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery();
		lqw.eq(Employee::getEmployeeName, name);
		Employee o = this.baseMapper.selectOne(lqw);
		lqw.last("limit 1");
		if (null != o) {
			return BeanCopyUtils.copy(o, EmployeeUserVo.class);
		}
		return null;
	}

	@Override
	public EmployeeUserVo getEmployeeUserVoByCode(String code) {
		LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery();
		lqw.eq(Employee::getEmployeeCode, code);
		lqw.last("limit 1");
		Employee o = this.baseMapper.selectOne(lqw);
		if (null != o) {
			return BeanCopyUtils.copy(o, EmployeeUserVo.class);
		}
		return null;
	}

	public Long getEmployeeIdByCode(String code) {
		LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery();
		lqw.eq(Employee::getEmployeeCode, code);
		lqw.last("limit 1");
		Employee o = this.baseMapper.selectOne(lqw);
		if (null != o) {
			return o.getId();
		}
		return null;
	}

	@Override
	public List<EmployeeImageDto> getEmployeeImageDtoList() {
		LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery();
		//lqw.eq(!StringUtils.isEmpty(date) , "query_time", date);
		lqw.not(s -> s.eq(Employee::getAvtar , ""));
		// qw.between("query_time", date, DateUtils.getNextDate(date, 1));
		// //service_time
		List<Employee> eList = this.baseMapper.selectList(lqw);
		
		if (null == eList || eList.isEmpty()) {
			eList = this.baseMapper.selectList();
		}
		
		List<EmployeeImageDto> list = eList.stream().map(e -> {
			EmployeeImageDto dto = new EmployeeImageDto();
			dto.setId(e.getId());
			dto.setPic1(e.getAvtar());
			if (StrUtil.isEmpty(dto.getPic1())) {
				dto.setPic1(ERecordConstant.DEFAULT_PIC_OSS_ID);
			}
			return dto;
		}).collect(Collectors.toList());
		return list;
	}

	@Override
	public List<EmployeeMapDetailDto> getEmployeeMapDetailDtoList(Integer serviceTypeId, String date) {
		LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery();
		// lqw.eq(!StringUtils.isEmpty(date), "query_time", date);
		// qw.between("query_time", date, DateUtils.getNextDate(date, 1));
		// //service_time
		lqw.eq(Employee::getServiceType, serviceTypeId);
		List<Employee> eList = this.baseMapper.selectList(lqw);
		List<EmployeeMapDetailDto> list = eList.stream().map(e -> {
			EmployeeMapDetailDto dto = new EmployeeMapDetailDto();
			dto.setId(e.getId());
			dto.setName(e.getEmployeeName());
			dto.setSerialNum(e.getEmployeeCode());
			dto.setPhone(e.getPhone());
			dto.setServiceTypeId(e.getServiceType());
			dto.setPostId(e.getPostId());
			return dto;
		}).collect(Collectors.toList());
		return list;
	}

	private String getEmpCodeById(Long id) {
		Employee e = this.baseMapper.selectById(id);
		if (null != e) {
			return e.getEmployeeCode();
		}
		return null;
	}
}
